﻿using Advantech.Common;
using EONFULLSIN2.Core;
using EONFULLSIN2.Core.EventArgs;
using EONFULLSIN2.Core.Extensions;
using EONFULLSIN2.Models.Attributes;
using EONFULLSIN2.Models.Entity.Device;
using EONFULLSIN2.Models.Enum.IOPointEnum;
using EONFULLSIN2.Models.Enum.SensorPoint;
using EONFULLSIN2.Services.DB;
using EONFULLSIN2.Services.Device.DIOModelA;
using EONFULLSIN2.Services.Device.DIOModelB;
using EONFULLSIN2.Services.Device.JuYing;
using EONFULLSIN2.Services.Device.ZhongChuangZhiHe;
using EONFULLSIN2.Services.Device.ZhuoLan;
using EONFULLSIN2.Services.Device.ZMoiton;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace EONFULLSIN2.Services.ControlService {

    /// <summary>
    /// -80度控制服务
    /// </summary>
    public class TempNegative80Service : ITempNegative80Service {

        private readonly IJuYingModbusService _juYingModbusService = null!;
        private readonly IZhuoLanModbusService _zhuoLanModbusService = null!;
        private readonly IZMoitonService _zMoitonService;
        private readonly IZczhModbusService _zczhModbusService;
        private IDbOperate<IFreeSqlMainContext> _mainDbOperate;
        private bool _isStart = false;
        private DateTime _unit01StartRunTime;
        private DateTime _unit02StartRunTime;

        public TempNegative80Service(
            IJuYingModbusService juYingModbusService,
            IZhuoLanModbusService zhuoLanModbusService,
            IZMoitonService zMoitonService,
            IZczhModbusService zczhModbusService,
            IDbOperate<IFreeSqlMainContext> mainDbOperate
            ) {
            this._juYingModbusService = juYingModbusService;
            this._zhuoLanModbusService = zhuoLanModbusService;
            this._zMoitonService = zMoitonService;
            this._zczhModbusService = zczhModbusService;
            this._mainDbOperate = mainDbOperate;
        }

        public event EventHandler RunStepEvent = null!;

        public async Task<bool> PreCoolingCoolingStartAsync() {
            bool result = false;
            if (!_isStart) {
                _isStart = true;
                try {
                    //1.判断环境温度是否大于35℃
                    var temp_TIC50006 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC50006);
                    if (temp_TIC50006 > 35) {
                        RunStepEventInvoke($"环境温度大于35℃，触发屏幕声光报警", "环境温度验证");
                        _isStart = false;
                        return false;
                    }

                    //2.启动机组1、机组2
                    double? i32001 = await _zczhModbusService.GetCurrentDataByIndexAsync(eCurrentPointEnum.I31001);
                    double? i42001 = await _zczhModbusService.GetCurrentDataByIndexAsync(eCurrentPointEnum.I42001);
                    if (i32001 >= 0.5 && i42001 < 0.5) {//启动机组2

                        result = await Unit02_StartAsync();

                    } else if (i32001 >= 0.5 && i42001 >= 0.5) {//机组1、机组2均已启动  DoNothing

                        RunStepEventInvoke($"双机组已启动！");

                    } else if (i32001 < 0.5 && i42001 >= 0.5) {//启动机组1

                        result = await Unit01_StartAsync();

                    } else if (i32001 < 0.5 && i42001 < 0.5) {//启动机组1、机组2

                        _ = Unit01_StartAsync();

                        _ = Unit02_StartAsync();

                    }

                } catch (Exception ex) {
                    _isStart = false;
                    RunStepEventInvoke($"预留降温流程步骤运行异常！");
                    LogManager.Error(ex);

                }
            } else {
                RunStepEventInvoke($"预留降温流程正在运行中，不可重复运行！");
            }

            return result;
        }

        public async Task<bool> LowTemperatureStandbyStartAsync() {
            bool result = false;
            if (!_isStart) {
                _isStart = true;
                try {

                    //1.判断环境温度是否大于35℃
                    var temp_TIC50006 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC50006);
                    if (temp_TIC50006 > 35) {
                        RunStepEventInvoke($"环境温度大于35℃，触发屏幕声光报警", "环境温度验证");
                        _isStart = false;
                        return false;
                    }

                    //2.启动机组1 或 机组2
                    double? i32001 = await _zczhModbusService.GetCurrentDataByIndexAsync(eCurrentPointEnum.I31001);
                    double? i42001 = await _zczhModbusService.GetCurrentDataByIndexAsync(eCurrentPointEnum.I42001);
                    if (i32001 >= 0.5 && i42001 >= 0.5) {//关闭机组1、机组2其中1个

                        if (_unit01StartRunTime >= _unit02StartRunTime) {
                            await Unit01_StopAsync();
                        } else {
                            await Unit02_StopAsync();
                        }

                    } else if (i32001 < 0.5 && i42001 < 0.5) {//启动机组1、机组2其中1个

                        var compressorLastStartTime1 = GetCompressorLastStartTime(eIOPointEnum.KM01);
                        var compressorLastStartTime2 = GetCompressorLastStartTime(eIOPointEnum.KM03);

                        if (compressorLastStartTime1 == null) {

                            await Unit01_StartAsync();

                        } else if (compressorLastStartTime2 == null) {

                            await Unit02_StartAsync();

                        } else if (compressorLastStartTime1.HasValue && compressorLastStartTime2.HasValue) {
                            //都不为null，启动上次启动时间较早的机组
                            if (compressorLastStartTime1.Value <= compressorLastStartTime2.Value) {
                                await Unit01_StartAsync();
                            } else {
                                await Unit02_StartAsync();
                            }
                        }
                    }

                } catch (Exception ex) {
                    _isStart = false;
                    RunStepEventInvoke($"预留降温流程步骤运行异常！");
                    LogManager.Error(ex);

                }
            } else {
                RunStepEventInvoke($"预留降温流程正在运行中，不可重复运行！");
            }

            return result;
        }

        public async Task<bool> ShutdownWarmingStartAsync() {
            bool result = false;
            //1.KA03、KA07、SSR03、SSR05 断开
            result = await SetIOChannelStatusAsync(eIOPointEnum.KA03, false);
            if (!result) return false;
            await Task.Delay(200);

            result = await SetIOChannelStatusAsync(eIOPointEnum.KA07, false);
            if (!result) return false;
            await Task.Delay(200);

            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR03, false);
            if (!result) return false;
            await Task.Delay(200);

            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR05, false);
            if (!result) return false;
            await Task.Delay(200);

            _ = Unit01_StopAsync();
            _ = Unit02_StopAsync();

            return result;
        }

        public Task<bool> DefrostStartAsync() {
            return DeFrost_StartAsync();
        }

        public Task<bool> DefrostStopAsync() {
            return DeFrost_StopAsync();
        }

        public async Task<bool> CabinDryStartAsync() {

            bool result = false;
            int waitTime = 0;

            //1.KA05、KA06 断开
            result = await SetIOChannelStatusAsync(eIOPointEnum.KA05, false);
            if (!result) return false;
            await Task.Delay(200);
            result = await SetIOChannelStatusAsync(eIOPointEnum.KA06, false);
            if (!result) return false;

            //2.判断门状态是否打开
            var vDoor = await _zczhModbusService.GetVoltageDataByIndexAsync(eVoltagePointEnum.V50001);
            if (vDoor >= 200) {
                RunStepEventInvoke($"门状态为关闭，无法启动舱内干燥，红灯闪烁提示", $"门状态验证失败，请打开舱门");
                //红灯闪烁提示 TODO
                return false;
            }

            //3.判断蒸发器温度
            var temp_TIC32016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC32016);
            var temp_TIC42016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC42016);
            while (!(temp_TIC32016 >= 10 && temp_TIC42016 >= 10)) {
                temp_TIC32016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC32016);
                temp_TIC42016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC42016);
                waitTime = 10 * 60 * 1000;
                RunStepEventInvoke($"机组1蒸发器出口温度，机组2蒸发器出口温度，均未大于10℃，等待10min", "温度未达到大于10℃，正在等待", new { WaitTime = waitTime / 1000 });
                await Task.Delay(waitTime);
            }

            //4.SSR01、SSR02、KA03 合上
            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, true);
            if (!result) return false;
            await Task.Delay(200);
            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, true);
            if (!result) return false;
            await Task.Delay(200);
            result = await SetIOChannelStatusAsync(eIOPointEnum.KA03, true);
            if (!result) return false;
            await Task.Delay(200);

            //5.运行15min
            int targetValue = 15 * 60; //干燥时间15min
            int elapsedTime = 0;//已运行时间s
            while (targetValue > elapsedTime) {
                var temp_TIC50005 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC50005);
                int witeTime = 1;
                RunStepEventInvoke($"舱内干燥中，已运行{elapsedTime}s，目标运行时间{targetValue}s", "舱内干燥，正在运行", new { ElapsedTime = elapsedTime, TargetValue = targetValue, Temp_TIC50005 = temp_TIC50005 });
                if (temp_TIC50005 <= 60) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR01, true);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR02, true);
                    await SetIOChannelStatusAsync(eIOPointEnum.KA03, true);

                } else if (temp_TIC50005 > 60) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
                    await Task.Delay(30 * 1000);
                    continue;

                }

                await Task.Delay(witeTime * 1000);//等待1秒
                elapsedTime = elapsedTime + witeTime;
            }

            //6.断开SSR01、SSR02、KA03
            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
            if (!result) return false;
            await Task.Delay(200);
            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
            if (!result) return false;
            await Task.Delay(200);
            result = await SetIOChannelStatusAsync(eIOPointEnum.KA03, false);
            if (!result) return false;
            await Task.Delay(200);

            return result;
        }

        public async Task<bool> CabinDryStopAsync() {

            bool result = false;

            //1.SSR01、SSR02、KA03 断开
            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
            if (!result) return false;
            await Task.Delay(200);

            result = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
            if (!result) return false;
            await Task.Delay(200);

            result = await SetIOChannelStatusAsync(eIOPointEnum.KA03, false);
            if (!result) return false;
            await Task.Delay(200);

            return result;
        }



        #region 私有通用方法 TODO

        /// <summary>
        /// 机组1启动(FA001)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> Unit01_StartAsync() {

            bool flag = false;

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA05, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA06, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA07, true);
            if (!flag) return false;
            await Task.Delay(200);

            int waitTime = 0;
            //1.【KA01】闭合，机组1冷凝风扇运行，计时器保持等待60s
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA01, true);
            if (!flag) return false;
            waitTime = 60 * 1000;
            RunStepEventInvoke($"机组1冷凝风扇，已启动，等待60s", $"机组1冷凝风扇，正在运行", new { WaitTime = waitTime / 1000 });
            await Task.Delay(waitTime);

            //2.【KM01】机组1压缩机01，判断上次停机时间是否超过180s，如果没有超过，等待至180s
            var compressorLastStartTime = GetCompressorLastStartTime(eIOPointEnum.KM01);
            if (compressorLastStartTime.HasValue) {
                var compressorLastStartSeconds = (int)(DateTime.Now - compressorLastStartTime.Value).TotalSeconds;
                if (compressorLastStartSeconds < 180) {
                    RunStepEventInvoke($"机组1压缩机01，距离上次启动间隔未满180s", "启动间隔未满180s，正在等待", new { WaitTime = compressorLastStartSeconds });
                    await Task.Delay(compressorLastStartSeconds * 1000);
                }
            }

            //3.【TIC31013】机组1冷凝器，判断温度是否小于等于50度，如果小于等于50度，启动机组1压缩机01（KM01），否则待机，触发AL21报警
            double temp = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC31013);
            if (temp <= 50) {
                flag = await SetIOChannelStatusAsync(eIOPointEnum.KM01, true);
                RunStepEventInvoke("机组1压缩机01，已启动", "机组1压缩机01，正在运行");
            } else {
                flag = false;
                RunStepEventInvoke("机组1冷凝器，温度大于50℃，机组1压缩机01，无法启动，触发报警AL21", $"当前温度：{temp}℃");
                //触发报警AL21
                //TODO
            }
            if (!flag) return false;

            //4.等待120s
            _unit01StartRunTime = DateTime.Now;//记录机组1压缩机启动时间
            waitTime = 120 * 1000;
            RunStepEventInvoke("机组1压缩机01，已启动，等待120s", "机组1压缩机01，正在等待", new { WaitTime = waitTime / 1000 });
            await Task.Delay(waitTime);


            //5.判断【TIC31018】机组1板换温度是否小于等于-20度，如果小于等于-20度，启动机组1压缩机02（KM02），否则等待10min，循环判断温度，触发AL23报警
            //6.判断【TIC31018】机组1板换温度是否大于等于-10度，如果大于等于-10度，停止机组1压缩机02（KM02），否则等待180s，继续循环判断温度
            while (true) {
                temp = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC31018);

                if (temp <= -10) {
                    break;//跳出循环
                } else if (temp > -10) {
                    waitTime = 3 * 60 * 1000;
                    flag = await SetIOChannelStatusAsync(eIOPointEnum.KM02, false);
                    RunStepEventInvoke($"机组1板换温度大于-10℃，等待{waitTime / 1000}s", "机组1板换温度大于-10℃，正在等待", new { WaitTime = waitTime / 1000 });
                } else if (temp <= -20) {
                    waitTime = 500;
                    flag = await SetIOChannelStatusAsync(eIOPointEnum.KM02, true);
                    RunStepEventInvoke("机组1压缩机02，已启动", "机组1压缩机02，正在运行");
                } else if (temp > -20) {
                    //触发AL23报警
                    //TODO
                    waitTime = 10 * 60 * 1000;
                    RunStepEventInvoke($"机组1板换温度大于-20℃，等待{waitTime / 1000}s", "机组1板换温度大于-20℃，正在等待", new { WaitTime = waitTime / 1000 });
                }
                await Task.Delay(waitTime);
            }
            if (!flag) return false;

            //7.判断【TIC32016】机组1板换温度\机组2板换温度是否小于等于-35度，如果小于等于-35度，启动循环风机01【KA03】，否则等待120s，循环判断温度
            var temp_TIC32016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC32016);
            while (temp_TIC32016 > -35) {
                waitTime = 2 * 60 * 1000;
                RunStepEventInvoke("机组1板换温度温度均大于-35℃，等待120s", "机组1板换温度过高，正在等待", new { WaitTime = waitTime / 1000 });
                await Task.Delay(waitTime);
            }
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA03, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR03, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR05, true);
            if (!flag) return false;
            await Task.Delay(200);

            return flag;
        }

        // <summary>
        /// 机组2启动(FA002)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> Unit02_StartAsync() {
            bool flag = false;

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA05, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA06, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA07, true);
            if (!flag) return false;
            await Task.Delay(200);

            int waitTime = 0;
            //1.【KA02】闭合，机组2冷凝风扇运行，计时器保持等待60s
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA02, true);
            if (!flag) return false;
            waitTime = 60 * 1000;
            RunStepEventInvoke("机组2冷凝风扇，已启动，等待60s", "机组2冷凝风扇，正在运行", new { WaitTime = waitTime / 1000 });
            await Task.Delay(waitTime);

            //2.【KM03】机组2压缩机01，判断上次停机时间是否超过180s，如果没有超过，等待至180s
            var compressorLastStartTime = GetCompressorLastStartTime(eIOPointEnum.KM03);
            if (compressorLastStartTime.HasValue) {
                var compressorLastStartSeconds = (int)(DateTime.Now - compressorLastStartTime.Value).TotalSeconds;
                if (compressorLastStartSeconds < 180) {
                    RunStepEventInvoke("机组2压缩机01，距离上次启动间隔未满180s", "启动间隔未满180s，正在等待", new { WaitTime = compressorLastStartSeconds });
                    await Task.Delay(compressorLastStartSeconds * 1000);
                }
            }

            //3.判断【TIC41013】机组2冷凝器温度是否小于等于50度，如果小于等于50度，启动机组2压缩机01（KM03），否则待机，触发AL22报警
            double temp = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC41013);
            if (temp <= 50) {
                flag = await SetIOChannelStatusAsync(eIOPointEnum.KM03, true);
                RunStepEventInvoke("机组2压缩机01，已启动", "机组2压缩机01，正在运行");
            } else {
                flag = false;
                RunStepEventInvoke("机组2冷凝器，温度大于50℃，机组2压缩机02，无法启动，触发报警AL22", $"当前温度：{temp}℃");
                //触发报警AL22
                //TODO
            }
            if (!flag) return false;

            //4.等待120s
            _unit01StartRunTime = DateTime.Now;//记录机组2压缩机启动时间
            waitTime = 120 * 1000;
            RunStepEventInvoke("机组2压缩机02，已启动，等待120s", "机组2压缩机02，正在等待", new { WaitTime = waitTime / 1000 });
            await Task.Delay(waitTime);


            //5.判断【TIC41018】机组2板换温度是否小于等于-20度，如果小于等于-20度，启动机组2压缩机02（KM04），否则等待10min，循环判断温度，触发AL23报警
            //6.判断【TIC41018】机组2板换温度是否大于等于-10度，如果大于等于-10度，停止机组2压缩机02（KM04），否则等待180s，继续循环判断温度
            while (true) {
                temp = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC41018);

                if (temp <= -10) {
                    break;//跳出循环
                } else if (temp > -10) {
                    waitTime = 3 * 60 * 1000;
                    flag = await SetIOChannelStatusAsync(eIOPointEnum.KM04, false);
                    RunStepEventInvoke($"机组2板换温度大于-10℃，等待{waitTime / 1000}s", "机组2板换温度大于-10℃，正在等待", new { WaitTime = waitTime / 1000 });
                } else if (temp <= -20) {
                    flag = await SetIOChannelStatusAsync(eIOPointEnum.KM04, true);
                    RunStepEventInvoke("机组2压缩机02，已启动", "机组2压缩机02已启动，正在运行");
                } else if (temp > -20) {
                    waitTime = 10 * 60 * 1000;
                    RunStepEventInvoke($"机组2板换温度大于-20℃，等待{waitTime / 1000}s", "机组2板换温度大于-20℃，正在等待", new { WaitTime = waitTime / 1000 });
                }
                await Task.Delay(waitTime);
            }
            if (!flag) return false;

            //7.判断【TIC42016】机组2板换温度\机组2板换温度是否小于等于-35度，如果小于等于-35度，启动循环风机02【KA03】，否则等待120s，循环判断温度
            var temp_TIC42016 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC42016);
            while (temp_TIC42016 > -35) {
                waitTime = 2 * 60 * 1000;
                RunStepEventInvoke("机组2板换温度均大于-35℃，等待120s", "机组2板换温度均大于-35度，正在等待", new { WaitTime = waitTime / 1000 });
                await Task.Delay(waitTime);
            }
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA03, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR03, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR05, true);
            if (!flag) return false;
            await Task.Delay(200);

            return flag;
        }

        /// <summary>
        /// 机组1停止(FA003)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> Unit01_StopAsync() {
            bool flag = false;
            //1.【KM02】断开，机组1压缩机02停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM02, false);
            if (!flag) return false;
            RunStepEventInvoke("机组1压缩机02停止", "机组1压缩机02，已停止");
            await Task.Delay(500);

            //2.【KM01】断开，机组1压缩机01停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM01, false);
            if (!flag) return false;
            RunStepEventInvoke("机组1压缩机01停止", "机组1压缩机01，已停止");
            await Task.Delay(500);

            //3.【KA01】断开，机组1冷凝风扇停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA01, false);
            if (!flag) return false;
            RunStepEventInvoke("机组1冷凝风扇停止", "机组1冷凝风扇，已停止");
            await Task.Delay(500);

            return flag;
        }

        /// <summary>
        /// 机组2停止(FA004)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> Unit02_StopAsync() {
            bool flag = false;
            //1.【KM04】断开，机组2压缩机02停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM04, false);
            if (!flag) return false;
            RunStepEventInvoke("机组2压缩机02停止", "机组2压缩机02，已停止");
            await Task.Delay(500);

            //2.【KM03】断开，机组2压缩机01停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM03, false);
            if (!flag) return false;
            RunStepEventInvoke("机组2压缩机01停止", "机组2压缩机01，已停止");
            await Task.Delay(500);

            //3.【KA02】断开，机组2冷凝风扇停止
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA02, false);
            if (!flag) return false;
            RunStepEventInvoke("机组2冷凝风扇停止", "机组2冷凝风扇，已停止");
            await Task.Delay(500);

            return flag;
        }

        /// <summary>
        /// 除霜启动(F401)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> DeFrost_StartAsync() {
            bool flag = false;
            int waitTime = 0;
            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA03, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR03, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR05, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM02, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KM04, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA05, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA06, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, true);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR04, true);
            if (!flag) return false;
            waitTime = 30 * 1000;
            RunStepEventInvoke("沉水盘加热器，已开启，等待30s", "沉水盘加热器，正在等待", new { WiteTime = waitTime / 1000 });
            await Task.Delay(waitTime);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA04, true);
            if (!flag) return false;

            int targetValue = 10 * 60; //除霜时间10min
            int elapsedTime = 0;//已运行时间s
            while (targetValue > elapsedTime) {

                var temp_TIC50005 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC50005);
                var temp_TIC50006 = await _juYingModbusService.GetSensorDataByIndexAsync(eTempPointEnum.TIC50006);
                int witeTime = 1;
                RunStepEventInvoke($"除霜中，已运行{elapsedTime}s，目标运行时间{targetValue}s", "除霜，正在运行", new { ElapsedTime = elapsedTime, TargetValue = targetValue, Temp_TIC50005 = temp_TIC50005, Temp_TIC50006 = temp_TIC50006 });
                if (temp_TIC50005 <= 60 && temp_TIC50006 <= 120) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR04, true);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR01, true);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR02, true);

                } else if (temp_TIC50005 <= 60 && temp_TIC50006 > 120) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR04, false);
                    await Task.Delay(30 * 1000);
                    continue;

                } else if (temp_TIC50005 > 60 && temp_TIC50006 > 120) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR04, false);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
                    await Task.Delay(30 * 1000);
                    continue;

                } else if (temp_TIC50005 > 60 && temp_TIC50006 <= 120) {

                    await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
                    await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
                    await Task.Delay(30 * 1000);
                    continue;

                }

                await Task.Delay(witeTime * 1000);//等待1秒
                elapsedTime = elapsedTime + witeTime;
            }

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA04, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR04, false);
            if (!flag) return false;
            await Task.Delay(200);

            //flag = await SetIOChannelStatusAsync(eIOPointEnum.KA08, true);
            //if (!flag) return false;
            //waitTime = 1 * 60 * 1000;
            //RunStepEventInvoke("沉水盘下水电磁阀，已开启，等待1min", "沉水盘下水电磁阀，正在等待", new { WiteTime = waitTime / 1000 });

            //flag = await SetIOChannelStatusAsync(eIOPointEnum.KA08, false);

            return flag;
        }

        /// <summary>
        /// 除霜停止(F402)
        /// </summary>
        /// <returns></returns>
        private async Task<bool> DeFrost_StopAsync() {
            bool flag = false;

            flag = await SetIOChannelStatusAsync(eIOPointEnum.KA04, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR01, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR02, false);
            if (!flag) return false;
            await Task.Delay(200);

            flag = await SetIOChannelStatusAsync(eIOPointEnum.SSR04, false);
            if (!flag) return false;
            await Task.Delay(200);

            //flag = await SetIOChannelStatusAsync(eIOPointEnum.KA08, false);
            //if (!flag) return false;
            //await Task.Delay(200);

            return flag;
        }



        //-----------------------------------------------------------------------------------------------------------//
        /// <summary>
        /// 设置IO通道状态
        /// </summary>
        /// <param name="eIOPointEnum"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        private async Task<bool> SetIOChannelStatusAsync(eIOPointEnum eIOPointEnum, bool status) {
            bool res = false;
            var eAdamModelType = eIOPointEnum.GetAttributeOfType<IOPointAttribute>();
            if (eAdamModelType != null) {
                RunStepEventInvoke($"设置IO通道状态，通道：{eAdamModelType.ChannelName}，描述：{eIOPointEnum.GetAttributeOfType<IOPointAttribute>().Description}，状态：{(status ? "打开" : "关闭")} 发送指令开始", $"{eIOPointEnum.GetAttributeOfType<IOPointAttribute>().Description}，{(status ? "打开" : "关闭")}");
                res = await _zMoitonService.SetOutPutStatusByIndexAsync(eIOPointEnum, status);
                if (res) {
                    //验证是否设置成功
                    var statusTemp = await _zMoitonService.GetSensorOutPutStatusByIndexAsync(eIOPointEnum);
                    if (statusTemp != status) {
                        res = false;
                    }

                }
                RunStepEventInvoke($"设置IO通道状态，通道：{eAdamModelType.ChannelName}，描述：{eIOPointEnum.GetAttributeOfType<IOPointAttribute>().Description}，状态：{(status ? "打开" : "关闭")} 发送指令结束，结果={res} ");
                if (res) {   
                    //记录设备运行状态
                    if (status) {
                        AddDeviceRunRecord(eIOPointEnum);
                    } else {
                        UpdateDeviceRunRecord(eIOPointEnum);
                    }
                }
            }
            return res;
        }


        /// <summary>
        /// 获取压缩机最后启动时间
        /// </summary>
        /// <param name="eIOPointEnum"></param>
        /// <returns></returns>
        private DateTime? GetCompressorLastStartTime(eIOPointEnum eIOPointEnum) {
            DateTime? lastStartTime = null;
            var eAdamModelType = eIOPointEnum.GetAttributeOfType<IOPointAttribute>();
            string codeNumber = eAdamModelType.Name;
            var model = _mainDbOperate.GetModel<DeviceRunRecord>(o => o.CodeNumber == codeNumber);
            if (model != null) {
                lastStartTime = model.EndTime;
            }
            return lastStartTime;
        }

        /// <summary>
        /// 新增设备运行记录
        /// </summary>
        /// <param name="eIOPointEnum"></param>
        /// <returns></returns>
        private bool AddDeviceRunRecord(eIOPointEnum eIOPointEnum) {
            bool res = false;
            var eAdamModelType = eIOPointEnum.GetAttributeOfType<IOPointAttribute>();
            string codeNumber = eAdamModelType.Name;
            var model = new DeviceRunRecord() {
                CodeNumber = codeNumber,
                Type = Models.Enum.eSensorTypeEnum.IOMdoel,
                Description = eAdamModelType.Description,
                StartTime = DateTime.Now
            };
            res = _mainDbOperate.AddModel<DeviceRunRecord>(model);
            return res;
        }

        /// <summary>
        /// 更新设备运行记录
        /// </summary>
        /// <param name="eIOPointEnum"></param>
        /// <returns></returns>
        private bool UpdateDeviceRunRecord(eIOPointEnum eIOPointEnum) {
            bool res = false;
            var eAdamModelType = eIOPointEnum.GetAttributeOfType<IOPointAttribute>();
            string codeNumber = eAdamModelType.Name;
            res = _mainDbOperate.UpdateModel<DeviceRunRecord>(o => o.CodeNumber == codeNumber && o.EndTime == null, o => new DeviceRunRecord { EndTime = DateTime.Now });
            return res;
        }


        /// <summary>
        /// 运行步骤事件触发
        /// </summary>
        /// <param name="message"></param>
        /// <param name="step"></param>
        /// <param name="data"></param>
        private void RunStepEventInvoke(string message, string step = "", object data = null) {
            var parasm = new DialogParameters();
            if (data != null) {
                parasm.Add("WaitTime", data);
            }
            RunStepEvent?.Invoke(this, new MessageEventArgs(message, step, parasm));
        }

        #endregion
    }
}
